
import os
import cv2 as cv
import numpy as np
import pickle
from imutils import paths
from sklearn.decomposition import PCA
from matplotlib import pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import sys,time




X0=[]
y1=[]
for f in os.listdir():
    if ".jpg" not in f: # 如果不是jpg图像文件，则略过
        continue
    img=cv.imread(f,0)
    img_gray = cv.equalizeHist(img)  # 对图像进行直方图增强

    # 1. 创建级联分类器
    face_cascade = cv.CascadeClassifier()
    # 2. 引入训练好的可用于人脸识别的级联分类器模型
    face_cascade.load("haarcascade_frontalface_alt.xml")
    # 3. 用此级联分类器识别图像中的所有人脸信息，返回一个包含有所有识别的人联系系的列表
    # 列表中每一个元素包含四个值：面部左上角的坐标(x,y) 以及面部的宽和高(w,h)
    faces = face_cascade.detectMultiScale(img_gray)

    for (x, y, w, h) in faces:
        cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        new0=img[y:y + h, x:x + w]
        new_img = cv.resize(new0, (224, 224), interpolation = cv.INTER_NEAREST)
        X0.append(new_img.ravel())

        if "wj" in f:
            y1.append('wj')
        elif "zxc" in f:
            y1.append('zxc')
        elif "zrf" in f:
            y1.append('zrf')
        elif "ldh" in f:
            y1.append('ldh')
        else:
            y1.append('hg')
    X = np.array(X0, dtype = object)
    y = np.array(y1)
with open("X", 'wb') as f:
    pickle.dump(X, f)
with open("y", 'wb') as f:
    pickle.dump(y, f)

with open("X", 'rb') as f:
   X = pickle.load(f)
with open("y", 'rb') as f:
   y = pickle.load(f)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)


# 3. 搜索最佳K
print("开始搜索最佳K:")
start = time.time() # <--- 开始计时
acc_list=[]
max_test=94
for k in range(1,max_test+1):
    clf = KNeighborsClassifier(n_neighbors=k) # 1. 创建分类器
    clf.fit(X_train, y_train)                 # 2. fit
    acc = clf.score(X_test, y_test)           # 3. score
   # print("K={0} 准确率: {1:.2f}%".format(k, acc * 100))
    acc_list.append(acc) # 纪律所有的准确率
end = time.time() # <--- 结束计时
print(max(acc_list))
# 保存最大准确率对应的knn
max_acc_k=np.argmax(acc_list)+1 # 利用最大准确率的位置得到对应的k：max_acc_k
# 训练出 max_acc_k 对应的 knn 模型
clf = KNeighborsClassifier(n_neighbors=max_acc_k).fit(X_train, y_train)
with open("knn", 'wb') as f:
    pickle.dump(clf, f)
    print("已保存具有最大准确率knn")

